﻿using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;

namespace SportTraining.MVVM.ViewModel.Impl
{
        public class ViewModelBase<TViewModel> : IViewModelBase where TViewModel : ViewModelBase<TViewModel>
        {
            public event PropertyChangedEventHandler PropertyChanged;

            protected void FirePropertyChanged(string property)
            {
                if (PropertyChanged != null)
                {
                    var args = new PropertyChangedEventArgs(property);
                    PropertyChanged(this, args);
                }
            }

            protected void FirePropertyChanged<TProperty>(Expression<Func<TViewModel, TProperty>> propertySelector)
            {
                var handler = PropertyChanged;
                if (handler != null)
                {
                    string propertyName;
                    switch (propertySelector.Body.NodeType)
                    {
                        case ExpressionType.MemberAccess:
                            {
                                var memberExpression = ((MemberExpression)propertySelector.Body);
                                if (memberExpression.Member.MemberType != MemberTypes.Property)
                                {
                                    throw new ArgumentException(string.Format("Wrong property selector: {0}!", propertySelector),
                                                                "propertySelector");
                                }
                                propertyName = memberExpression.Member.Name;
                                break;
                            }
                        default:
                            {
                                throw new ArgumentException(string.Format("Wrong property selector: {0}!", propertySelector),
                                                                "propertySelector");
                            }
                    }
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
}